﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lottery.Model;
using System.IO;
using log4net;
using Lottery.Classes;
using CsvHelper.Configuration;
using Lottery.Error;

namespace Lottery.Data
{
    public class StaffData
    {
        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private static StaffData instances = null;

        private StaffData()
        {
            if (staffs == null || staffs.Count <= 0)
            {
                this.reload();
            }
        }

        public void reload()
        {
            this.staffs.Clear();
            staffs = this.loadStaffs(MyResources.GetConfigPath(MyResources.StaffsName));

        }

        public static StaffData Instances
        {
            get
            {
                if (instances == null)
                    instances = new StaffData();
                return instances;
            }
        }

        private List<StaffInfo> staffs = new List<StaffInfo>();

        public List<StaffInfo> Staffs
        {
            get { return staffs; }
            set { staffs = value; }
        }



  

        public List<StaffInfo> loadStaffs(String fileName)
        {
            List<StaffInfo> allStaff = new List<StaffInfo>();
            TxtData<StaffInfo> txtData = new TxtData<StaffInfo>(MyResources.GetConfigPath(MyResources.StaffsName));
            txtData.SkipLine = 3;
            txtData.ClassMap = typeof(StaffInfoMap);
            allStaff = txtData.readToObject();
            foreach (StaffInfo staff in allStaff)
            {
                if (WinnerData.Instances.existStaff(staff.JobNo) > 0)
                {
                    Console.WriteLine("工号{0}，{1}已经中奖", staff.JobNo, staff.Name);
                }
                else
                {
                    this.staffs.Add(staff);
                }
            }
            //此处打乱了数组下标，weihangl
            return this.random(staffs);
            //  return this.staffs;
        }


        public sealed class StaffInfoMap : ClassMap<StaffInfo>
        {
            public StaffInfoMap()
            {
                Map(m => m.JobNo).Name("工号");
                Map(m => m.Name).Name("姓名");
                Map(m => m.Dept).Name("部门");
                Map(m => m.Company).Name("公司");
            }
        }


        /// <summary>
        ///  随机排列数组中的数值顺序
        ///  技巧：顺次把数组中的数值和数组随机值置换位置
        /// </summary>
        /// <param name="strarr">被排列的数组strarr</param>
        private List<StaffInfo> random(List<StaffInfo> strarr)
        {
            Random ran = new Random();
            int k = 0;
            StaffInfo strtmp = null;
            int MaxLength = strarr.Count;
            for (int i = 0; i < strarr.Count; i++)
            {
                k = ran.Next(MaxLength);
                if (k != i)
                {
                    strtmp = strarr[i];
                    strarr[i] = strarr[k];
                    strarr[k] = strtmp;
                }
            }
            return strarr;
        }

        public StaffInfo RandomStaff()
        {

            if (this.staffs.Count <= 0)
            {
                throw new NoneStaffError();
            }
            StaffInfo staff = this.staffs.OrderBy(_ => Guid.NewGuid()).FirstOrDefault();
            staff.StaffIndex = System.Guid.NewGuid().ToString();
            return staff;
        }

        public StaffInfo RandomStaff(GiftInfo gift)
        {
            if (gift.OddNumber <= 0)
            {
                log.InfoFormat("奖品已经被抽完不产生中奖者");
                throw new GiftNoNumberError();
            }
            GroupRule groupRule = GroupRuleData.Instances.findRandomRuleByGift(gift);
            if (groupRule != null)
                log.InfoFormat("奖品{0}{1},锁定的规则公司是:{2}", gift.LevelName, gift.Name, groupRule.Company);
            return RandomStaffByGroup(groupRule);
        }

        private StaffInfo RandomStaffByGroup(GroupRule groupRule)
        {
            try
            {
                StaffInfo staff = this.RandomStaff();
                if (groupRule != null)
                {
                    var temp = from s in this.staffs
                               where string.IsNullOrEmpty(groupRule.Dept) ? s.Company.Equals(groupRule.Company) : s.Company.Equals(groupRule.Company) && s.Dept.Equals(groupRule.Dept)
                               //join rule in GroupRuleData.Instances.GroupRules on s.Company equals rule.Company
                               select s;
                    //List<StaffInfo> tempStaffs = this.staffs.Where(item => groupRule.match(item.Company, item.Dept)).ToList();
                    List<StaffInfo> tempStaffs = temp.Distinct().ToList<StaffInfo>();
                    if (tempStaffs.Count <= 0)
                        log.InfoFormat("对应的规则{0}没有数据", groupRule.Company);
                    staff = tempStaffs.OrderBy(_ => Guid.NewGuid()).FirstOrDefault();
                }
                else
                {
                    log.InfoFormat("没有匹配到规则");
                }
                if (staff == null)
                {
                    log.InfoFormat("没有匹配到人员使用随机规则");
                    staff = this.RandomStaff();
                }
                staff.StaffIndex = System.Guid.NewGuid().ToString();
                log.InfoFormat("找出的人是{0}公司{1}的{2}", staff.JobNo, staff.Company, staff.Name);
                return staff;
            }
            catch (Exception e)
            {
                log.Error("随机查找员工失败", e);
                return null;
            }

        }

        public void removeWinner(StaffInfo staff)
        {
            try
            {
                if (staff == null)
                    return;
                log.InfoFormat("删除中奖员工:{0},{1}", staff.JobNo, staff.Name);
                this.staffs.Remove(staff);

            }
            catch (Exception e)
            {
                log.Error(e);
            }
        }




    }
}
